package de.hsb.ai.agent.misterx.brain.history;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import de.hsb.ai.agent.misterx.brain.Brain;
import game.Move;


public class MoveHistory {

	private ArrayList<Move> _moves = new ArrayList<Move>(); 
	
	/**
	 * fügt einen Move hinzu.
	 * @param move
	 */
	public void addMove(Move move) {
		this._moves.add(move);
	}
	
	/**
	 * gibt die Größe der History zurück.
	 * @return
	 */
	public int size() {
		return this._moves.size();
	}
	
////////////////////////////////////////////////////////////////////////	
// MOVE CAPTURING
////////////////////////////////////////////////////////////////////////
	
	/**
	 * gibt Move zurück.
	 */
	public Move getMove(int index) {
		if(index >= 0 && index < this._moves.size()) {
			return this._moves.get(index);
		}
		return null;
	
	}
	
	/**
	 * gibt Ticket eines Moves zurück.
	 * @param index
	 * @return
	 */
	public int getNodeType(int index) {
		return this._moves.get(index).getType();
	}
	
	/**
	 * gibt NodeIndex zurück.
	 * @param index
	 * @return
	 */
	public int getNodeIndex(int index) {
		return this._moves.get(index).getNode();
	}
	
	/**
	 * gibt den letzten bekannten Move zurück.
	 * @return
	 */
	public Move getLastMove() {
		if(this._moves.size()-1 >= 0) {
			return this.getMove(this._moves.size()- 1);
		}
		return null;
	}
	
////////////////////////////////////////////////////////////////////////
// MOVEDIRECTION CAPTURING
////////////////////////////////////////////////////////////////////////	
	
	/**
	 * gibt die gesammte Bewegungsrichtung von der ersten gemachten Bewegung aus zurück.
	 */
	public Point2D getFullMovingDirection() {
		return this.getMovingDirection(this._moves.size()- 1);
	}
	
	/**
	 * gibt die letzte Bewegungsrichtung zurück.
	 * @return
	 */
	public Point2D getLastMovingDirection() {
		return this.getMovingDirection(1);
	}
	
	/**
	 * Ermittelt die Bewegungsrichtung eines Spielers über einen gewissen Zeitraum.
	 * @return
	 */
	public Point2D getMovingDirection(int prevSteps) {
		int prevStepIndex = (this._moves.size()- 1) - prevSteps;
		if((prevStepIndex) < 0) return null; //wenn es nicht genug vorSchritte gibt beende Funktion.
		if((prevStepIndex) >= this._moves.size()) return null; //verhindert negative Zahl eingabe.
		
		Move lastMove = this.getLastMove();
		Move prevMove = this._moves.get(prevStepIndex);
		if(lastMove != null) {
			return Brain.GEOANALYSER.getDifferenceVector(prevMove.getNode(), lastMove.getNode());
		}
		return null;
	}

	/**
	 * gibt die Bewegunsrichtung anhand des Indexes zurück.
	 * @param index
	 * @return
	 */
	public Point2D getMovingDirectionByIndex(int index) {
		if(index > 0 && index < this._moves.size()) {
		
			Move movePre = this._moves.get(index-1);
			Move move = this._moves.get(index);
			if(movePre != null && move != null) {
				return Brain.GEOANALYSER.getDifferenceVector(movePre.getNode(), move.getNode());
			}
		}
		return null;
	}

		
////////////////////////////////////////////////////////////////////////
//
////////////////////////////////////////////////////////////////////////		
	
	/**
	 * String-Repräsentation des Objekts.
	 */
	public String toString() {
		String data = "";
		for(Move move : this._moves) {
			data += move.toString() + ";";
		}
		return data;
	}
	
	/**
	 * gibt alle verbrauchten Tickets zurück (Ticket, Anzahl)
	 */
	public Map<Integer, Integer> getSpentTickets() {
		Map<Integer, Integer> tickets = new HashMap<Integer, Integer>();
		for(Move move : this._moves) {
			int ticketTyp = move.getType();
			if(tickets.containsKey(ticketTyp)) {
				tickets.put(ticketTyp, tickets.get(ticketTyp) + 1);
			} else {
				tickets.put(ticketTyp, 1);
			}
		}
		return tickets;
	}
	
}
